package com.zb.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zb.constant.StoreConstant;
import com.zb.entity.SelectResultVo;
import com.zb.entity.SelectStoreTypeVo;
import com.zb.entity.SelectVo;
import com.zb.entity.ZjStoreType;
import com.zb.mapper.ZjStoreTypeMapper;
import com.zb.result.PageUtil;
import com.zb.service.ZjStoreInboundService;
import com.zb.service.ZjStoreOutboundService;
import com.zb.service.ZjStoreTypeService;
import com.zb.vo.StoreTypeListSelectVo;
import com.zb.vo.StoreTypeListVo;
import com.zb.vo.StoreTypeVo;
import org.ehcache.sizeof.SizeOf;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 仓储类型表 服务实现类
 * </p>
 *
 * @author WEN
 * @since 2024-01-06
 */
@Service
public class ZjStoreTypeServiceImpl extends ServiceImpl<ZjStoreTypeMapper, ZjStoreType> implements ZjStoreTypeService {
    @Resource
    private ZjStoreTypeMapper storeTypeMapper;
    @Resource
    private ZjStoreInboundService storeInboundService;
    @Resource
    private ZjStoreOutboundService storeOutboundService;

    // 默认保存仓库出入库类型
    @Override
    public void saveDefaultStoreType(Long custAccId) {
        List<ZjStoreType> storeTypes = new ArrayList<>();
        storeTypes.add(ZjStoreType.inStoreType(custAccId, "工单配件旧件入库", true));
        storeTypes.add(ZjStoreType.inStoreType(custAccId, "其他入库", false));
        storeTypes.add(ZjStoreType.outStoreType(custAccId, "工单配件出库", true));
        storeTypes.add(ZjStoreType.outStoreType(custAccId, "销售出库", false));
        storeTypes.add(ZjStoreType.outStoreType(custAccId, "其他出库", false));
        this.saveBatch(storeTypes);
    }

    // 新增或修改仓库类型
    @Override
    public void save(Long custAccId, StoreTypeVo storeTypeVo) {
        Assert.isNull(storeTypeMapper.existByName(custAccId, storeTypeVo.getType(), storeTypeVo.getId(), storeTypeVo.getName()), "仓库类型名称已重复");

        List<ZjStoreType> updateTypes = new ArrayList<>();
        ZjStoreType storeType = null;
        Long id = null;
        if (storeTypeVo.getType() == StoreConstant.STORE_OUT_IN_TYPE_1) {
            storeTypeVo.setOutStoreOrderSpareType(false);
            id = storeTypeMapper.getInStoreOrderSpareTypeIdByCustAccId(custAccId);
            if (null == id && !storeTypeVo.getInStoreOrderSpareType()) {
                storeTypeVo.setInStoreOrderSpareType(true);
            } else {
                if (Objects.equals(id, storeTypeVo.getId()) && !storeTypeVo.getInStoreOrderSpareType()) {
                    Assert.isTrue(false, "当前类型为工单配件入库默认启用类型，如不启用，必须先指定一个启用类型方可取消当前类型的启用状态");
                }
                if (!Objects.equals(id, storeTypeVo.getId()) && storeTypeVo.getInStoreOrderSpareType()) {
                    storeType = new ZjStoreType();
                    storeType.setId(id);
                    storeType.setInStoreOrderSpareType(false);
                    updateTypes.add(storeType);
                }
            }
        } else {
            storeTypeVo.setInStoreOrderSpareType(false);
            id = storeTypeMapper.getOutStoreOrderSpareTypeIdByCustAccId(custAccId);
            if (null == id && !storeTypeVo.getOutStoreOrderSpareType()) {
                storeTypeVo.setOutStoreOrderSpareType(true);
            } else {
                if (Objects.equals(id, storeTypeVo.getId()) && !storeTypeVo.getOutStoreOrderSpareType()) {
                    Assert.isTrue(false, "当前类型为工单配件出库默认启用类型，如不启用，必须先指定一个启用类型方可取消当前类型的启用状态");
                }
                if (!Objects.equals(id, storeTypeVo.getId()) && storeTypeVo.getOutStoreOrderSpareType()) {
                    storeType = new ZjStoreType();
                    storeType.setId(id);
                    storeType.setOutStoreOrderSpareType(false);
                    updateTypes.add(storeType);
                }
            }
        }
        ZjStoreType type = new ZjStoreType();
        BeanUtil.copyProperties(storeTypeVo, type);
        type.setDisabled(storeTypeVo.getStatus());
        if (null != type.getId()) {
            updateTypes.add(type);
        } else {
            type.setId(IdWorker.getId());
            type.setCustAccId(custAccId);
            this.save(type);
        }
        if (CollectionUtil.isNotEmpty(updateTypes)) this.updateBatchById(updateTypes);
    }

    // 获取仓库类型列表
    @Override
    public Map<String, Object> getList(Long custAccId, StoreTypeListSelectVo selectVo) {
        PageUtil.setPageLimit(selectVo);
        List<ZjStoreType> types =  storeTypeMapper.getList(custAccId, selectVo);
        return PageUtil.pageList(selectVo.getPage(), selectVo.getLimit(), storeTypeMapper.getListCount(custAccId, selectVo), types.stream().map(type -> {
            StoreTypeListVo vo = new StoreTypeListVo();
            BeanUtil.copyProperties(type, vo);
            vo.setStatus(type.getDisabled());
            vo.setCreateTime(type.getGmtCreate());
            vo.setUpdateTime(type.getGmtUpdate());
            return vo;
        }).toList());
    }

    // 根据仓库类型ID获取详情
    @Override
    public StoreTypeVo getDetail(Long id) {
        ZjStoreType storeType = this.getById(id);
        Assert.notNull(storeType, "仓库类型数据不存在");
        StoreTypeVo vo = new StoreTypeVo();
        BeanUtil.copyProperties(storeType, vo);
        vo.setStatus(storeType.getDisabled());
        return vo;
    }

    // 批量启用或禁用仓库类型
    @Override
    public void updateDisableBatchById(List<Long> ids, Boolean status) {
        if (CollectionUtil.isEmpty(ids)) {
            return;
        }
        storeTypeMapper.updateDisableBatchById(ids, status);
    }

    // 批量删除仓库类型
    @Override
    public void deleteBatchById(List<Long> ids) {
        if (CollectionUtil.isEmpty(ids)) {
            return;
        }
        List<Long> typeIds = storeInboundService.getTypeIdByDelTypeIds(ids);
        exceptionMessage(typeIds, false);
        typeIds = storeOutboundService.getTypeIdByDelTypeIds(ids);
        exceptionMessage(typeIds, true);
        storeTypeMapper.deleteBatchById(ids);
    }

    private void exceptionMessage(List<Long> typeIds, boolean outStore) {
        if (CollectionUtil.isEmpty(typeIds)) {
            return;
        }
        QueryWrapper<ZjStoreType> wrapper = new QueryWrapper<>();
        wrapper.select("name");
        wrapper.in("id", typeIds);
        String types = this.list(wrapper).stream().map(ZjStoreType::getName).collect(Collectors.joining("、"));
        Assert.isTrue(false, outStore? "出入库类型[ "+types+" ]已与入库单关联，禁止删除" : "出入库类型[ "+types+" ]已与出库单关联，禁止删除");
    }

    // 出库仓库类型下拉列表查询
    @Override
    public Map<String, Object> outStoreTypePageSelect(Long custAccId, Integer type, SelectVo selectVo) {
        PageUtil.setSelectPageLimit(selectVo);
        QueryWrapper<ZjStoreType> wrapper = new QueryWrapper<>();
        wrapper.orderByAsc(type == 1? "is_in_store_order_spare_type" : "is_out_store_order_spare_type").orderByDesc("gmt_update");
        wrapper.select("id", "name", "is_out_store_order_spare_type AS outStoreOrderSpareType", "is_in_store_order_spare_type AS inStoreOrderSpareType");
        wrapper.eq("cust_acc_id", custAccId)
                .eq("type", type)
                .eq("is_disabled", false);
        if (StringUtils.isNotBlank(selectVo.getName())) {
            wrapper.like("name", selectVo.getName());
        }
        Page<ZjStoreType> page = this.page(new Page<>(selectVo.getPage(), selectVo.getLimit()), wrapper);
        return PageUtil.pageList(page.getCurrent(), page.getSize(), page.getTotal(), page.getRecords().stream().map(storeType -> {
            return new SelectStoreTypeVo(storeType.getId(), storeType.getName(), storeType.getOutStoreOrderSpareType(), storeType.getInStoreOrderSpareType());
        }).toList());
    }

    // 根据商家ID获取默认出库工单配件的类型ID
    @Override
    public Long getOutStoreOrderSpareTypeIdByCustAccId(Long custAccId) {
        return storeTypeMapper.getOutStoreOrderSpareTypeIdByCustAccId(custAccId);
    }

    // 根据商家ID获取默认入库工单配件的类型ID
    @Override
    public Long getInStoreOrderSpareTypeIdByCustAccId(Long custAccId) {
        return storeTypeMapper.getInStoreOrderSpareTypeIdByCustAccId(custAccId);
    }

    // 根据ID获取出入库类型
    @Override
    public List<ZjStoreType> getNameByIds(List<Long> ids) {
        if (CollectionUtil.isEmpty(ids)) {
            return new ArrayList<>();
        }
        QueryWrapper<ZjStoreType> wrapper = new QueryWrapper<>();
        wrapper.select("id", "name");
        wrapper.in("id", ids);
        return this.list(wrapper);
    }

}
